// test.h
//
// Unit Test for synchronization

#include "lock.h"
#include "thread.h"

#include "unitTest.h"

using namespace simple;

namespace simple_test{
    class thread1 : public Thread
    {
        void thread ();
    };

    void thread1::thread ()
    {
        for (int i=0; i<10; i++) {
            std::cout << i << std::endl;
            sleep (100);
        }
    }



    UTFUNC(threads)
    {
        setDescription ("threads");

        thread1 threadInst1, threadInst2;
        threadInst1.start ();
        threadInst2.start ();

        // We can call WaitForMultipleObjects, but in case this is on
        // unix.
        //  HANDLE handles[2];
        //  handles[0] = (HANDLE) thread1.threadid ();
        //  handles[1] = (HANDLE) thread2.threadid ();
        //  WaitForMultipleObjects (2, handles, TRUE, INFINITE);

        threadInst1.wait ();
        threadInst2.wait ();
    }


    // Chapter 4 (pg 129) comment regarding RAII
    class ConsoleLocker
    {
    public:
        ConsoleLocker () { _consoleLock.lock();}
        ~ConsoleLocker () { _consoleLock.unlock();}

    private:
        static Lock _consoleLock;

        // Prohibit copy and assignment
        ConsoleLocker            (const ConsoleLocker& src);
        ConsoleLocker& operator= (const ConsoleLocker& src);
    };
    Lock ConsoleLocker::_consoleLock;


    UTFUNC(consoleLocker)
    {
        setDescription ("Console locking");

        {
            ConsoleLocker lock;
            std::cout << "Wow!" << std::endl;
        }

        VERIFY (true);
    }


    Lock mylock;

    UTFUNC(Locker)
    {
        setDescription ("Locker");

        {
            Locker lock(mylock);
            std::cout << "Wow!" << std::endl;
        }

        VERIFY (true);
    }

}
